package edu.hawaii.wattdepotapps.browser;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.wicket.model.Model;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import edu.hawaii.wattdepotapps.BasePage;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * Contains the class for the BrowserPage.html. Not yet implemented. Only drop-down menu of sources
 * has been coded.
 * 
 * @author Edward Meyer, Kendyll Doi, Bao Huy Ung
 * @version 0.1
 */
public class BrowserPage extends BasePage {

  /**
   * Makes the page serializable.
   */
  private static final long serialVersionUID = -5719619758599534459L;

  /** Holds the connection to a WattDepot server. */
  private static WattDepotClient client;

  /**
   * Calls the create methods of the pages interface and connects to wattdepot.
   * 
   */
  public BrowserPage() {

    // Holds the Form for the page.
    Form<String> pageForm = null;
    pageForm = new Form<String>("BrowserForm") {

      /** Support serialization. */
      private static final long serialVersionUID = 1L;
    };

    // To start the Browser page, connect to the Wattdepot server to query data.
    // Last 2 params are null as they are used for username and password.
    connect("http://server.wattdepot.org:8194/wattdepot/", null, null);

    // Adds the source drop-down menu to the page form.
    pageForm = createSourceDropDown(pageForm);

    add(pageForm);

  }

  /**
   * Connect method to create connection to WattDepot Service.
   * 
   * @param uri contains a string of the uri to connect to WattDepot.
   * @param username a string of a user on the WattDepot.
   * @param password a string of the user's password to WattDepot.
   * @return a string with output of method.
   */
  private String connect(String uri, String username, String password) {

    client = new WattDepotClient(uri, username, password);
    // Stop right away if we cannot contact server.
    if (!client.isHealthy()) {
      return "Failed to connect to " + client.getWattDepotUri();
    }
    // Indicate successful connection.
    return "Connected to " + client.getWattDepotUri();
  }

  /**
   * Returns a list of strings of all the names in a WattDepot server.
   * 
   * @return A list of String names of all sources.
   * @throws MiscClientException If error is encountered retrieving sources, or some unexpected
   * problem is encountered.
   * @throws BadXmlException If error is encountered unmarshalling the XML from the server.
   * @throws NotAuthorizedException If the client is not authorized to retrieve sources.
   */
  private List<String> getClientSources() throws NotAuthorizedException, BadXmlException,
      MiscClientException {

    // Create a list of all sources in the WattDepot server.
    List<Source> allSources = client.getSources();
    List<String> names = new ArrayList<String>();

    // Loop through each source and add the name to the list.
    for (Source source : allSources) {
      names.add(source.getName());
    }

    // Return all the names in the list.
    return names;
  }

  /**
   * Creates the DropDownMenu of all sources the client has access to in the WattDepot server. If
   * any errors occur during retrieval process, display "No Sources" on the page, and output error
   * message to console.
   * 
   * @param form Holds the page's form.
   * @return a Form<String> object with objects added.
   */
  private Form<String> createSourceDropDown(Form<String> form) {

    // Holds the list of all sources.
    List<String> sourceList;

    // Attempt to get the list of all sources in the client.
    try {
      sourceList = getClientSources();
    }
    // Server does not allow anonymous/public access.
    catch (NotAuthorizedException e) {
      sourceList = Arrays.asList("No Sources");
      System.err.format("Error: Client %s does not allow public/anonymous access.", client
          .getWattDepotUri());
    }
    // Received bad XML from server.
    catch (BadXmlException e) {
      sourceList = Arrays.asList("No Sources");
      System.err.println("Error: Received bad XML from server.");
    }
    // Any other miscellaneous errors that occur will be caught by MiscClientException.
    catch (MiscClientException e) {
      sourceList = Arrays.asList("No Sources");
      System.err.println("Error: Had problems retrieving sources from server, "
          + "please check your connection.");
    }

    // Initialize the dropdown menu field.
    DropDownChoice<String> dropSources =
        new DropDownChoice<String>("Source", new Model<String>(sourceList.get(0)), sourceList);
    dropSources.setRequired(true);

    // Add the dropdown menu to the page.
    form.add(dropSources);

    return form;
  }

}